/*************************************************************************
	> File Name: waitid.c
	> Author: Angel Criss
	> Blog: blog.abbycin.tk 
	> Created Time: Mon 07 Jul 2014 08:43:32 PM CST
 ************************************************************************/
#define _XOPEN_SOURCE 500  // compromise between sigaction and waitid
#include "head.h"

void dealing(int sig,siginfo_t *info,void *uncontext)
{
    printf("got signal \e[32m %d \e[0m\n",sig);
    printf("si_code: %d; si_pid: %ld; si_signo: %d; si_status: %d; si_uid (Signal sender's UID): %d\n",info->si_code,info->si_pid,info->si_signo,info->si_status,info->si_uid);
    return;
}

int main(int argc,char *argv[])
{
    pid_t child;
    int out;
  //  idtype_t idtype;
    struct sigaction act;
    siginfo_t info;

    sigemptyset(&act.sa_mask);
    act.sa_sigaction=dealing;
    act.sa_flags=SA_SIGINFO;
    sigaddset(&act.sa_mask,SIGSTOP);

    if(sigaction(SIGINT,&act,NULL)==-1)
        err("sigaction");

    for(;;)
    {
        switch(child=fork())
        {
            case -1:
                err("fork");
            case 0:
                printf("(child) PID: %d\n",getpid());
                for(;;)
                    pause();
                exit(EXIT_SUCCESS);
            default:
                for(;;)
                {
                    out=waitid(P_PID,child,&info,WSTOPPED|WCONTINUED|WEXITED); // assume this system support these feature
                    if(out==0)
                        printf("due to change of state of one of its children\n"); // see manpage for more
                    else if(out==-1)
                        err("waitid");
    printf("\n\e[36msi_code: %d; si_pid: %ld; si_signo: %d; si_status: %d; si_uid (process owner's UID): %d\e[0m\n",info.si_code,info.si_pid,\
            info.si_signo,info.si_status,info.si_uid);

                p_wait_status(NULL,info.si_status); // pass status to status-dealing function

                }
        }
    }
}
